//FacePos.h 
//created by Robin
#ifndef FACELOCATION_H
#define FACELOCATION_H

#include <iostream>
#include <vector>
#include <atlbase.h>
#include <atlstr.h>
#include "PackBuffer.h"

#pragma warning(disable : 4996 )
class CRegion  
{
public:
    char    m_szFileName[_MAX_PATH];
    int     m_iRegionID;
    int     m_iLabel;
    int     m_iClassifyResult;
	RECT	m_Rect;
	float   m_fConfidence;
	union {
		int		m_nRotationDegree;
		struct {
			__int16 m_nProfileView;
			__int16 m_nInplaneView;
		};
	};
	int		m_nLayerPassed;
	int		m_nScaleNo;
	int		m_nOverlapTiers;

	char   m_szPerson[_MAX_PATH];
    CRegion()
    {
		memset(this, 0, sizeof(CRegion));
    }
	int GetWidth() const { return m_Rect.right-m_Rect.left; 	}
	int GetHeight() const { return m_Rect.bottom-m_Rect.top;	}
	int GetArea( ) const { return GetWidth()*GetHeight(); }
	void WriteData(FILE* fdata)
	{
        fprintf(fdata, "%2d %2d %4d %4d %4d %4d %5.3f %3d %2d %2d %3d %s\n", 
			m_iRegionID, m_iLabel, 
			m_Rect.left, m_Rect.top, m_Rect.right, m_Rect.bottom, 
			m_fConfidence,
			m_nRotationDegree,
			m_nLayerPassed,
			m_nScaleNo,
			m_nOverlapTiers,
			m_szFileName);
		return;
	}
	BOOL   ReadData(FILE* fdata)
	{
		fscanf(fdata, "%d %d %d %d %d %d %f %d %d %d %d", 
			&m_iRegionID, &m_iLabel, 
			&m_Rect.left, &m_Rect.top, &m_Rect.right, &m_Rect.bottom,
			&m_fConfidence,
			&m_nRotationDegree,
			&m_nLayerPassed,
			&m_nScaleNo,
			&m_nOverlapTiers
			);

		fgets(m_szFileName, _MAX_PATH - 1, fdata);
		char *p = strrchr(m_szFileName, '\n');
		if (p != NULL)
			*p = 0;
		CString strFileName = m_szFileName;
		strFileName.TrimLeft(); strFileName.TrimRight();
		strcpy(m_szFileName, strFileName);

		return true;
	}
};

class RegionGreater {
public:
	BOOL operator() (const CRegion& ra, const CRegion& rb) const
	{
		return _stricmp(ra.m_szFileName,rb.m_szFileName)>=0;
	}
};

class CRegionSet
{
public:
   char   m_szPathName[_MAX_PATH];
   int      m_iImageNumber;
   std::vector<CRegion> m_arrRegion;

   CRegionSet()
   {
	   m_iImageNumber = 0;
	   m_szPathName[0] = 0;
   }

   int ReadRegions(const char* szRegionFile)
   {
      FILE*   fp;
      if( (fp  = fopen(szRegionFile, "r" )) == NULL )
      {
         printf( "Error! The position file %s can not be opened\n", szRegionFile);
         return -1;
      };
      fgets(m_szPathName, _MAX_PATH, fp);
      m_szPathName[strlen(m_szPathName)-1] = 0;
	  int nRegionNum = 0;
      fscanf(fp, "%d %d", &m_iImageNumber, &nRegionNum);
      char temp[256];
      fgets(temp, 256, fp);
      m_arrRegion.clear();
      for (int i = 0 ;i < nRegionNum; i++)
      {
         CRegion region;
         region.ReadData(fp);
         m_arrRegion.push_back(region);
      }
      fclose(fp);
      return m_iImageNumber;
   }
   
   int WriteRegions(const char* szRegionFile)
   {
      FILE*   fp;
      if( (fp  = fopen(szRegionFile, "w" )) == NULL )
      {
         printf( "Error! The position file %s can not be opened\n", szRegionFile);
         return -1;
      };
      fprintf(fp, "%s\n", m_szPathName);
      fprintf(fp, "%d\n%d\n", m_iImageNumber, m_arrRegion.size());
      for (unsigned int i = 0 ;i < m_arrRegion.size(); i++)
      {
         CRegion& region=m_arrRegion[i];
         region.WriteData(fp);
      }
	  fclose(fp);
      return m_iImageNumber;
   }

   PackIt::CPackBuffer ToPackBuffer() const
   {
	   PackIt::CPackBuffer pb;
	   pb.Pack(
		   PackIt::PackBufferArrayIn<char>(m_szPathName, _MAX_PATH), 
		   m_iImageNumber,
		   (int)m_arrRegion.size());

	   for(size_t i = 0; i<m_arrRegion.size(); i++)
	   {
		   const CRegion& rg = m_arrRegion[i];
		   pb.Pack(
			   PackIt::PackBufferArrayIn<char>(rg.m_szFileName, _MAX_PATH),
			   rg.m_iRegionID,
			   rg.m_iLabel,
				rg.m_iClassifyResult,
			   rg.m_fConfidence,
			   rg.m_nRotationDegree,
			   rg.m_nLayerPassed,
			   rg.m_nScaleNo,
			   rg.m_nOverlapTiers,
			   PackIt::PackBufferArrayIn<char>(rg.m_szPerson, _MAX_PATH)
			   );

		   pb.Pack(rg.m_Rect.left, rg.m_Rect.right, rg.m_Rect.top, rg.m_Rect.bottom);

	   }
	   return pb;
   }

   bool Depack(PackIt::CDepacker& dp)
   {
	   int iRegionSize = 0;
	   if(!dp.Read(
		   PackIt::PackBufferArrayOut<char>(m_szPathName, _MAX_PATH),
		   m_iImageNumber,
		   iRegionSize
		   ))
	   {
		   std::cout<<"Read Region set path name failed!"<<std::endl;
		   return false;
	   }

	   for(int i = 0; i<iRegionSize; i++)
	   {
		   CRegion rg;
		   if(!dp.Read(
			   PackIt::PackBufferArrayOut<char>(rg.m_szFileName, _MAX_PATH),
			   rg.m_iRegionID,
			   rg.m_iLabel,
			   rg.m_iClassifyResult,
			   rg.m_fConfidence,
			   rg.m_nRotationDegree,
			   rg.m_nLayerPassed,
			   rg.m_nScaleNo,
			   rg.m_nOverlapTiers,
			   PackIt::PackBufferArrayOut<char>(rg.m_szPerson, _MAX_PATH)
			   ))
		   {
			   std::cout<<"Read Region set detail failed!"<<std::endl;
			   return false;
		   }

		   if(!dp.Read(rg.m_Rect.left, rg.m_Rect.right, rg.m_Rect.top, rg.m_Rect.bottom))
		   {
			   std::cout<<"Read Region rect failed!"<<std::endl;
			   return false;
		   }

		   m_arrRegion.push_back(rg);

	   }
	   return true;
   }
   
};


#endif // FACELOCATION_H